home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Tools / Utility / PCISlots / Sources / PCISlots.cp next >
Encoding:
Text File  |  1996-08-20  |  14.4 KB  |  541 lines  |  [TEXT/MPS ]

  1. // Copyright © 1995 by Apple Computer, Inc.  All rights reserved.
  2. // PCISlots.cp
  3.  
  4. /*
  5. FILE
  6.     PCISlots.cp
  7.  
  8. NAME
  9.     PCI Slot Peek source file
  10.  
  11. DESCRIPTION
  12.     This source file implements the PCI Slot Peek application.
  13.  
  14. MODIFICATION HISTORY
  15.     Created by Terry Teague
  16.  
  17.     20 Apr 95    -    TRT    -    Initial version
  18.     01 Jun 95    -    TRT    -    Add support for finding slot # given driver refNum.
  19.                                     Provide separate and generic setup/teardown routines for PPC native code
  20.     12 Jun 95    -    TRT    -    Changed error handling for PCI on machines that don't have the slots
  21.                                     but do have NameRegistry support in ROM/System software
  22.     17 Jul 95    -    TRT    -    Tidy-up source for PPCC v1.0.5, Universal Headers v2.0 final,
  23.                                     CodeWarrior 6.1.
  24.  
  25. =============================================================================================
  26. */
  27.  
  28. //================================================================================================
  29. // Build-time #defines
  30. //================================================================================================
  31.  
  32. // pre-Universal Headers (<MPW 3.3.1) compatibility
  33. #ifndef    qPreUniHeaders
  34. #define    qPreUniHeaders        0
  35. #endif
  36.  
  37. //================================================================================================
  38. // Standard Includes
  39. //================================================================================================
  40.  
  41. #include <Types.h>
  42. #include <Packages.h>
  43. #include <Dialogs.h>
  44. #include <Memory.h>
  45. //#if    qPreUniHeaders
  46. //#include <OSEvents.h>
  47. //#endif
  48. #include <QuickDraw.h>
  49. #include <Resources.h>
  50. #include <ToolUtils.h>
  51. #include    <StdIO.h>
  52. #include    <Slots.h>
  53. #include    <ROMDefs.h>
  54. #include    <Devices.h>
  55. #include    <Traps.h>
  56. #include    <String.h>
  57. #include    <Strings.h>
  58. #include    <CType.h>
  59. #if    qPreUniHeaders
  60. #include    <SysEqu.h>
  61. #else
  62. #include    <LowMem.h>
  63. #endif
  64. #include    <Power.h>
  65. #include    <DeskBus.h>
  66.  
  67. // v2.0 final or later
  68. #ifndef __CODEFRAGMENTS__
  69. #include    <CodeFragments.h>
  70. #endif
  71.  
  72. // v2.0a3 or earlier (also kept in v2.0 final for compatibility)
  73. //#ifndef __FRAGLOAD__
  74. //#include    <FragLoad.h>
  75. //#endif
  76.  
  77. #ifndef __MIXEDMODE__
  78. #include    <MixedMode.h>
  79. #endif
  80.  
  81. // v2.0a3 or earlier
  82. //#ifndef    __GESTALTEQU__
  83. //#include    <GestaltEqu.h>
  84. //#endif
  85.  
  86. // v2.0 final or later
  87. #ifndef    __GESTALT__
  88. #include    <Gestalt.h>
  89. #endif
  90.  
  91. // v2.0a3 or earlier
  92. #ifdef    __FRAGLOAD__
  93. typedef SInt32 OSStatus;
  94. #endif
  95.  
  96. #ifndef    __NAMEREGISTRY__
  97. #include    <NameRegistry.h>
  98. #endif
  99.  
  100. //================================================================================================
  101. // PCISlots Specific Includes
  102. //================================================================================================
  103.  
  104. #ifndef    __PCISLOTS__
  105. #include    "PCISlots.h"
  106. #endif
  107.  
  108. #ifdef __cplusplus
  109. extern "C" {
  110. #endif
  111.  
  112. #if GENERATINGPOWERPC || defined(powerc) || defined (__powerc)
  113. #pragma options align=mac68k
  114. #endif
  115.  
  116. #ifdef __CFM68K__
  117. #pragma lib_export on
  118. #endif
  119.  
  120. //================================================================================================
  121. // Global variables
  122. //================================================================================================
  123.  
  124. #if GENERATINGPOWERPC || defined(powerc) || defined (__powerc)
  125.     
  126. #else
  127.  
  128.     // 68K code only
  129.     // these have to be A5 based global variables
  130.     
  131.     RegistryEntryIterateCreateUPP        myRegistryEntryIterateCreateUPP;
  132.     RegistryEntryIterateDisposeUPP    myRegistryEntryIterateDisposeUPP;
  133.     RegistryEntryIterateUPP                myRegistryEntryIterateUPP;
  134.     RegistryEntryIDDisposeUPP            myRegistryEntryIDDisposeUPP;
  135.     RegistryPropertyGetSizeUPP            myRegistryPropertyGetSizeUPP;
  136.     RegistryPropertyGetUPP                myRegistryPropertyGetUPP;
  137.     RegistryEntryToPathSizeUPP            myRegistryEntryToPathSizeUPP;
  138.     RegistryCStrEntryToPathUPP            myRegistryCStrEntryToPathUPP;
  139.  
  140. #endif
  141.  
  142. //================================================================================================
  143. // Setup PPC native code glue
  144. //================================================================================================
  145.  
  146. #if GENERATINGPOWERPC || defined(powerc) || defined (__powerc)
  147.     
  148. #else
  149.  
  150.     // 68K code only
  151.  
  152. OSErr SetupPPCNativeCode(CFragConnectionID *connID, Handle *PEFHandle)
  153. {
  154.     OSErr                        myErr;
  155.             
  156.     long                        templong;
  157.  
  158.     Boolean                    hasCFM;
  159.     Boolean                    hasMixedMode;
  160.     CFragSymbolClass        myClass;
  161.     Str255                    failedFragName;
  162.     
  163.     //DebugStr("\pAbout to setup PPC native code");
  164.     
  165.     myErr = noErr;
  166.     
  167.     *PEFHandle = Get1Resource(kPEFResType, kPEFresourceID);    // get PEF container resource from our resource fork
  168.     if (*PEFHandle && !(myErr = ResError()))
  169.     {
  170.         // Check for Mixed Mode Manager and Code Fragment Manager (CFM)
  171.         
  172.         hasMixedMode = !Gestalt(gestaltMixedModeAttr, &templong);
  173.         hasCFM = !Gestalt(gestaltCFMAttr, &templong);
  174.         
  175.         myErr = Gestalt(gestaltSysArchitecture, &templong);
  176.         if (myErr || (templong == gestalt68k))
  177.         {
  178.             ReleaseResource(*PEFHandle);
  179.             
  180.             return (glueNotPPCErr);
  181.         }
  182.         
  183.         if (!hasCFM || !hasMixedMode)
  184.         {
  185.             ReleaseResource(*PEFHandle);
  186.             
  187.             return (glueNoCFMorMMErr);
  188.         }
  189.         
  190.         DetachResource(*PEFHandle);
  191.         MoveHHi(*PEFHandle);
  192.         HLock(*PEFHandle);
  193.         
  194.         // Assume this is PowerPC code, so it must be "prepared"
  195.         myErr = GetMemFragment((Ptr)**PEFHandle, 0, NULL, kNewCFragCopy, connID, NULL, failedFragName);
  196.         if (myErr)
  197.         {
  198.             //DebugStr(failedFragName);    // at present
  199.             DisposeHandle(*PEFHandle);
  200.  
  201.             return (glueCFMPrepareErr);
  202.         }
  203.  
  204.         myErr = FindSymbol(*connID, (ConstStr255Param)"\pRegistryEntryIterateCreateRD", (Ptr *)&myRegistryEntryIterateCreateUPP, &myClass);
  205.         if (!myErr)
  206.             myErr = FindSymbol(*connID, (ConstStr255Param)"\pRegistryEntryIterateDisposeRD", (Ptr *)&myRegistryEntryIterateDisposeUPP, &myClass);
  207.         if (!myErr)
  208.             myErr = FindSymbol(*connID, (ConstStr255Param)"\pRegistryEntryIterateRD", (Ptr *)&myRegistryEntryIterateUPP, &myClass);
  209.         if (!myErr)
  210.             myErr = FindSymbol(*connID, (ConstStr255Param)"\pRegistryEntryIDDisposeRD", (Ptr *)&myRegistryEntryIDDisposeUPP, &myClass);
  211.         if (!myErr)
  212.             myErr = FindSymbol(*connID, (ConstStr255Param)"\pRegistryPropertyGetSizeRD", (Ptr *)&myRegistryPropertyGetSizeUPP, &myClass);
  213.         if (!myErr)
  214.             myErr = FindSymbol(*connID, (ConstStr255Param)"\pRegistryPropertyGetRD", (Ptr *)&myRegistryPropertyGetUPP, &myClass);
  215.         if (!myErr)
  216.             myErr = FindSymbol(*connID, (ConstStr255Param)"\pRegistryEntryToPathSizeRD", (Ptr *)&myRegistryEntryToPathSizeUPP, &myClass);
  217.         if (!myErr)
  218.             myErr = FindSymbol(*connID, (ConstStr255Param)"\pRegistryCStrEntryToPathRD", (Ptr *)&myRegistryCStrEntryToPathUPP, &myClass);
  219.         
  220.         if (myErr)
  221.         {
  222.             //DebugStr("\pa NameRegistryLib symbol could not be found");    // at present
  223.             
  224.             DisposeHandle(*PEFHandle);
  225.             
  226.             return (glueFindSymbolErr);
  227.         }
  228.     
  229.     } else
  230.     
  231.     {
  232.         myErr = glueNoGlueErr;
  233.     }
  234.  
  235.     return (myErr);
  236.         
  237. }    /* setupppcnativecode */
  238.  
  239. //================================================================================================
  240. // Tear down PPC native code glue
  241. //================================================================================================
  242. void TearDownPPCNativeCode(CFragConnectionID connID, Handle PEFHandle)
  243. {
  244. #if 0
  245.         // don't need to close the connection?
  246.         if (myRegistryEntryIterateCreateUPP)
  247.             DisposeRoutineDescriptor(myRegistryEntryIterateCreateUPP);
  248.         if (myRegistryEntryIterateDisposeUPP)
  249.             DisposeRoutineDescriptor(myRegistryEntryIterateDisposeUPP);
  250.         if (myRegistryEntryIterateUPP)
  251.             DisposeRoutineDescriptor(myRegistryEntryIterateUPP);
  252.         if (myRegistryEntryIDDisposeUPP)
  253.             DisposeRoutineDescriptor(myRegistryEntryIDDisposeUPP);
  254.         if (myRegistryPropertyGetSizeUPP)
  255.             DisposeRoutineDescriptor(myRegistryPropertyGetSizeUPP);
  256.         if (myRegistryPropertyGetUPP)
  257.             DisposeRoutineDescriptor(myRegistryPropertyGetUPP);
  258.         if (myRegistryEntryToPathSizeUPP)
  259.             DisposeRoutineDescriptor(myRegistryEntryToPathSizeUPP);
  260.         if (myRegistryCStrEntryToPathUPP)
  261.             DisposeRoutineDescriptor(myRegistryCStrEntryToPathUPP);
  262. #endif
  263.  
  264.         CloseConnection(&connID);
  265.         
  266.         DisposeHandle(PEFHandle);
  267.  
  268. }    /* teardownppcnativecode */
  269.         
  270. #endif
  271.  
  272. // I could have implemented the same code for 68K and native PPC
  273. // if I had used macros as per PCISlots.h, but I didn't
  274.  
  275. #if GENERATINGPOWERPC || defined(powerc) || defined (__powerc)
  276.  
  277. //================================================================================================
  278. // Get PCI slot # for specified driver refNum (not used in this application)
  279. //================================================================================================
  280. short GetPCISlotNumber(short refNum)
  281. {
  282.     short                            slotNum;
  283.     
  284.     slotNum = 0;
  285.     
  286.     slotNum = GetSlotForThisRefNum(refNum);
  287.             
  288.     return (slotNum);
  289.  
  290. }    /* getpcislotnumber */
  291.  
  292. #else
  293.  
  294.     // 68K code only
  295.  
  296. //================================================================================================
  297. // Get PCI slot # for specified driver refNum (not used in this application)
  298. //================================================================================================
  299. short GetPCISlotNumber(short refNum)
  300. {
  301.     OSErr                            myErr;
  302.     CFragConnectionID            connID;
  303.     Handle                        PEFHandle;
  304.     short                            slotNum;
  305.     
  306.     slotNum = 0;
  307.     
  308.     if ((myErr = SetupPPCNativeCode(&connID, &PEFHandle)) == noErr)
  309.     {
  310.         // 68K application calling native PPC code at this point
  311.         
  312.         //DebugStr("\pAbout to call 68K->PPC glue code");
  313.         slotNum = GetSlotForThisRefNum(refNum);
  314.         
  315.         TearDownPPCNativeCode(connID, PEFHandle);
  316.     } else
  317.     
  318.     {
  319.         // handle errors when trying to set up PPC native glue code
  320.     }
  321.             
  322.     return (slotNum);
  323.  
  324. }    /* getpcislotnumber */
  325.  
  326. #endif
  327.  
  328. //================================================================================================
  329. // PCISlots main program
  330. //================================================================================================
  331.  
  332. int main(void)
  333. {
  334.     OSErr                theErr;
  335.     short                numSlots;
  336.     
  337.     long                templong;
  338.     char                tempstr[256];
  339.     
  340. #if GENERATINGPOWERPC || defined(powerc) || defined (__powerc)
  341.     
  342.     // native PPC application only
  343.     
  344.     // If the NameRegistryLib is weak-linked, and it is missing, we need to
  345.     // check for the library, to prevent a crash if we try to access the library's exports;
  346.     // currently Finder reports the library is missing
  347.  
  348. #if 1
  349.     CFragConnectionID        connID;
  350.     Ptr                        mainAddr;
  351.     Str255                    errName;
  352.     
  353.     getindstring(tempstr, kMiscPCISTRID, kPCISlotsTitle);    // formatting string
  354.     printf("%s", tempstr);
  355.     
  356.     theErr = Gestalt(gestaltCFMAttr, &templong);
  357.     if (!theErr)
  358.     {
  359.         theErr = GetSharedLibrary((ConstStr63Param)"\pNameRegistryLib", kAnyCFragArch, kFindCFrag, &connID, &mainAddr, errName);
  360.     }
  361. #endif
  362.  
  363.     if (theErr)
  364.     {
  365.         // No Code Fragment Manager, hence no shared library
  366.         // or the shared library is missing
  367.  
  368.         getindstring(tempstr, kMiscPCISTRID, kNoNameRegistryLib);    // formatting string
  369.         printf("%s", tempstr);
  370.         
  371.         return (1);
  372.     }
  373.     
  374.     //DebugStr((const unsigned char*)"\pAbout to do NameRegistry Gestalt call");
  375.     theErr = Gestalt(gestaltNameRegistryVersion, &templong);
  376.     if (theErr)
  377.     {
  378.         getindstring(tempstr, kMiscPCISTRID, kNoPCISlots);    // formatting string
  379.         printf("%s", tempstr);
  380.         return (1);
  381.     }
  382.     
  383.     numSlots = EnumerateNameRegistry();
  384.  
  385.     if (!numSlots)
  386.     {
  387.         getindstring(tempstr, kMiscPCISTRID, kNoCardsInPCISlots);    // formatting string
  388.         printf("%s", tempstr);
  389.     }
  390.     
  391.     return (0);
  392.  
  393. #else
  394.  
  395.     // 68K application only
  396.     
  397.     Boolean                                    hasPCI;
  398.     CFragConnectionID                        connID;
  399.     Handle                                    PEFHandle;
  400.     
  401.     //DebugStr("\pAbout to get PCI Info");
  402.     
  403.     if ((theErr = SetupPPCNativeCode(&connID, &PEFHandle)) == noErr)
  404.     {
  405.         // Output title
  406.         
  407.         getindstring(tempstr, kMiscPCISTRID, kPCISlotsTitle);    // formatting string
  408.         printf("%s", tempstr);
  409.         
  410.         // If the NameRegistryLib is weak-linked, and it is missing, we need this
  411.         // Gestalt check anyway, to prevent a crash if we try to access the library's exports
  412.         
  413.         //DebugStr((const unsigned char*)"\pAbout to do NameRegistry Gestalt call");
  414.         hasPCI = !Gestalt(gestaltNameRegistryVersion, &templong);
  415.         
  416.         theErr = Gestalt(gestaltSysArchitecture, &templong);
  417.         if (theErr || (templong == gestalt68k) || !hasPCI)
  418.         {
  419.             getindstring(tempstr, kMiscPCISTRID, kNoPCISlots);    // formatting string
  420.             printf("%s", tempstr);
  421.             
  422.             TearDownPPCNativeCode(connID, PEFHandle);
  423.             
  424.             return (1);
  425.         }
  426.         
  427.         // 68K application calling native PPC code at this point
  428.         
  429.         numSlots = EnumerateNameRegistry();
  430.         
  431.         TearDownPPCNativeCode(connID, PEFHandle);
  432.             
  433.         if (!numSlots)
  434.         {
  435.             getindstring(tempstr, kMiscPCISTRID, kNoCardsInPCISlots);    // formatting string
  436.             printf("%s", tempstr);
  437.         }
  438.         
  439.         return (0);
  440.         
  441.     } else
  442.     
  443.     if (theErr != glueNoGlueErr)
  444.     {
  445.         // handle errors when trying to set up PPC native glue code - at present
  446.  
  447.         short            tempint;
  448.         
  449.         tempint = 0;
  450.         
  451.         switch (theErr) {
  452.         case glueNotPPCErr        :    tempint = kNoPCISlots;
  453.                                             break;
  454.         case glueNoCFMorMMErr    :    tempint = kNo68KNameRegistry;
  455.                                             break;
  456.         case glueCFMPrepareErr    :    tempint = kNoNameRegistryLib;
  457.                                             break;
  458.         case glueFindSymbolErr    :    tempint = kNoNameRegistryLib;
  459.                                             break;
  460.         default                        :    tempint = kNoNameRegistryLib;
  461.                                             break;
  462.         }    // switch
  463.         
  464.         if (tempint)
  465.         {
  466.             // Output title
  467.             
  468.             getindstring(tempstr, kMiscPCISTRID, kPCISlotsTitle);    // formatting string
  469.             printf("%s", tempstr);
  470.         
  471.             getindstring(tempstr, kMiscPCISTRID, tempint);    // formatting string
  472.             printf("%s", tempstr);
  473.         }
  474.     } else
  475.     
  476.     {
  477.  
  478.         long            Architecture;
  479.         short                itemHit;
  480.         AlertTHndl        theAlertTemplate;
  481.         Handle            theDITLHandle;
  482.         Str255            theMessage;
  483.         
  484.         // There is no native PPC code available, or we are running on a true 68K machine
  485.         
  486.         InitGraf((Ptr)&qd.thePort);
  487.         InitFonts();
  488.         InitWindows();
  489.         InitMenus();
  490.         TEInit();
  491.         InitDialogs(nil);
  492.         InitCursor();
  493.         
  494.         // set cursor to an arrow
  495.         SetCursor(&qd.arrow);
  496.     
  497.         // pre-flight everything first
  498.         
  499.         theAlertTemplate = (AlertTHndl)GetResource('ALRT', kNotPPCResourceID);        // is the ALRT resource around?
  500.         if (theAlertTemplate)
  501.             theDITLHandle = GetResource('DITL', (*theAlertTemplate)->itemsID);    // How about the DITL?
  502.             
  503.         theErr = Gestalt(gestaltSysArchitecture, &Architecture);                 // Which message to print?
  504.         if (theErr || (Architecture == gestalt68k) )
  505.             GetIndString(theMessage, kNotPPCResourceID, kMac68KMsgID);
  506.          else
  507.             GetIndString(theMessage, kNotPPCResourceID, kPowerMacMsgID);
  508.     
  509.         if ((theAlertTemplate) && (theDITLHandle) && (theMessage[0] != 0))
  510.         {
  511.             // Success at last...
  512.         
  513.             ParamText(theMessage, (ConstStr255Param) "\p",                 // Use the loaded STR resource to replace
  514.                           (ConstStr255Param) "\p", (ConstStr255Param) "\p");    //    ^0 in alert's DITL.
  515.             itemHit = Alert(kNotPPCResourceID, nil);                                // Run the alert.
  516.         } else
  517.         
  518.         {
  519.             // give some indication we're hosed...
  520.             SysBeep(2); 
  521.         }
  522.         
  523.         return (1);
  524.  
  525.     }
  526. #endif
  527.  
  528. }    /* main */
  529.  
  530. #ifdef __CFM68K__
  531. #pragma lib_export off
  532. #endif
  533.  
  534. #if GENERATINGPOWERPC || defined(powerc) || defined (__powerc)
  535. #pragma options align=reset
  536. #endif
  537.  
  538. #ifdef __cplusplus
  539. }
  540. #endif
  541.